package com.yonyou.pmclouds.task.processor;

import com.yonyou.pmclouds.alter.entity.AlterVO;
import com.yonyou.pmclouds.alter.mapper.AlterMapper;
import com.yonyou.pmclouds.alterandvisa.entity.AlterAndVisaVO;
import com.yonyou.pmclouds.alterandvisa.mapper.AlterAndVisaMapper;
import com.yonyou.pmclouds.alterandvisacategory.rmiitf.AlterAndVisaCategoryQuery;
import com.yonyou.pmclouds.altercategory.rmiitf.AlterCategoryQuery;
import com.yonyou.pmclouds.basecom.bp.processor.MultiProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.SingleProcessor;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.dao.BaseMapper;
import com.yonyou.pmclouds.basecom.entity.Entity;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.util.SqlUtil;
import com.yonyou.pmclouds.comprehensiveacceptance.entity.ComprehensiveAcceptanceVO;
import com.yonyou.pmclouds.comprehensiveacceptance.mapper.ComprehensiveAcceptanceVOMapper;
import com.yonyou.pmclouds.constructiondiary.entity.ConstructionDiaryVO;
import com.yonyou.pmclouds.constructiondiary.mapper.ConstructionDiaryMapper;
import com.yonyou.pmclouds.constructionlog.entity.ConstructionLogVO;
import com.yonyou.pmclouds.constructionlog.mapper.ConstructionLogMapper;
import com.yonyou.pmclouds.plan.entity.PlanWriteVO;
import com.yonyou.pmclouds.plan.entity.ProjectPlanVO;
import com.yonyou.pmclouds.plan.mapper.PlanWriteMapper;
import com.yonyou.pmclouds.plan.mapper.ProjectPlanMapper;
import com.yonyou.pmclouds.problemlog.entity.ProblemLogVO;
import com.yonyou.pmclouds.problemlog.mapper.ProblemLogMapper;
import com.yonyou.pmclouds.procedure.entity.ProcedureRefVO;
import com.yonyou.pmclouds.procedure.rmiitf.ProcedureQuery;
import com.yonyou.pmclouds.procedureinspect.mapper.ProcedureInspectMapper;
import com.yonyou.pmclouds.processinspect.entity.ProcedureInspectVO;
import com.yonyou.pmclouds.processphoto.entity.ProcessPhotoVO;
import com.yonyou.pmclouds.processphoto.mapper.ProcessPhotoMapper;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.reason.entity.ProblemReasonRefVO;
import com.yonyou.pmclouds.reason.rmiitf.ProblemReasonQuery;
import com.yonyou.pmclouds.repeatwork.entity.RepeatWorkVO;
import com.yonyou.pmclouds.repeatwork.mapper.RepeatWorkMapper;
import com.yonyou.pmclouds.repeatwork.service.rmiitf.IRepeatWorkQuery;
import com.yonyou.pmclouds.safetyrectification.entity.SafetyRectificationVO;
import com.yonyou.pmclouds.safetyrectification.mapper.SafetyRectificationMapper;
import com.yonyou.pmclouds.siteinspection.mapper.SiteInspectionMapper;
import com.yonyou.pmclouds.stagecheck.mapper.StageCheckMapper;
import com.yonyou.pmclouds.task.entity.TaskVO;
import com.yonyou.pmclouds.workConnect.entity.WorkConnectVO;
import com.yonyou.pmclouds.workconnect.mapper.WorkConnectMapper;
import com.yonyou.pmclouds.workquality.entity.WorkqualityVO;
import com.yonyou.pmclouds.workquality.service.rmiitf.WorkqualityQueryService;
import com.yonyou.pmclouds.workstartreport.entity.WorkStartVO;
import com.yonyou.pmclouds.workstartreport.mapper.WorkStartMapper;
import com.yonyou.pmclouds.workstopreport.entity.WorkStopVO;
import com.yonyou.pmclouds.workstopreport.mapper.WorkStopMapper;
import com.yonyou.pmclouds.workstopreport.rmiitf.WorkStopQuery;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 待办任务保存前规则
 *
 * @zhangwce
 */
@Component
public class TaskBeforeInsertProcessor implements SingleProcessor<TaskVO>,MultiProcessor<TaskVO>,InitializingBean {

    private Map<String,BaseMapper> mapperMap = new HashMap<>();

    @Autowired
    private WorkConnectMapper workConnectMapper;
    @Autowired
    private ProblemLogMapper problemLogMapper;
    @Autowired
    private ProcedureInspectMapper procedureInspectMapper;
    @Autowired
    private ProcedureQuery procedureQuery;
    @Autowired
    private AlterAndVisaMapper alterAndVisaMapper;
    @Autowired
    private AlterAndVisaCategoryQuery alterAndVisaCategoryQuery;
    @Autowired
    private AlterCategoryQuery alterCategoryQuery;
    @Autowired
    private ComprehensiveAcceptanceVOMapper comprehensiveAcceptanceVOMapper;
    @Autowired
    private ConstructionLogMapper constructionLogMapper;
    @Autowired
    private WorkqualityQueryService qualityQuery;
    @Autowired
    private ProcessPhotoMapper processPhotoMapper;
    @Autowired
    private AlterMapper alterMapper;
    @Autowired
    private ProjectPlanMapper projectPlanMapper;
    @Autowired
    private ConstructionDiaryMapper constructionDiaryMapper;
    @Autowired
    private SiteInspectionMapper siteInspectionMapper;
    @Autowired
    private ProblemReasonQuery problemReasonQuery;
    @Autowired
    private WorkStartMapper workStartMapper;
    @Autowired
    private ProjectSimpleQuery projectSimpleQuery;
    @Autowired
    private PlanWriteMapper planWriteMapper;
    @Autowired
    private SafetyRectificationMapper safetyRectificationMapper;
    @Autowired
    private WorkStopMapper workStopMapper;
    @Autowired
    private WorkStopQuery workStopQuery;
    @Autowired
    private StageCheckMapper stageCheckMapper;
    @Autowired
    private RepeatWorkMapper repeatWorkMapper;
    @Autowired
    private IRepeatWorkQuery repeatWorkQuery;

    @Override
    public void process(TaskVO vo, TaskVO orig) throws BusinessException {
        this.process(new TaskVO[]{vo},null);
    }

    @Override
    public void process(TaskVO[] taskVOs, TaskVO[] origTaskVOs) throws BusinessException {
        if (ArrayUtils.isEmpty(taskVOs))
            return;
        Set<String> pkBills = new HashSet<>();
        String billType = null;
        for (TaskVO vo : taskVOs) {
            if (vo == null)
                continue;
            if (vo.getPk_bill() != null)
                pkBills.add(vo.getPk_bill());
            if (billType == null && vo.getSrc_bill_type() != null)
                billType = vo.getSrc_bill_type();
        }
        if (billType == null || pkBills.isEmpty())
            return;

        Map<String, String> recordInfo = getTaskDescribeMap(billType, pkBills.toArray(new String[0]));
        for (TaskVO vo : taskVOs) {
            if (vo != null)
                vo.setBillDescribe(recordInfo.get(vo.getPk_bill()));
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        mapperMap.put(BillTypeConst.WORKCONNECT_BILLTYPE,workConnectMapper);
        mapperMap.put(BillTypeConst.PROBLEMLOG_BILLTYPE,problemLogMapper);
        mapperMap.put(BillTypeConst.PROCEDUREINSPECT_BILLTYPE,procedureInspectMapper);
        mapperMap.put(BillTypeConst.ALTER_AND_VISA_BILLTYPE,alterAndVisaMapper);
        mapperMap.put(BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE,comprehensiveAcceptanceVOMapper);
        mapperMap.put(BillTypeConst.CONSTRUCTIONLOG_BILLTYPE,constructionLogMapper);
        mapperMap.put(BillTypeConst.PROCESSPHOTO_BILLTYPE,processPhotoMapper);
        mapperMap.put(BillTypeConst.ALTER_BILLTYPE,alterMapper);
        mapperMap.put(BillTypeConst.PROCESS_PLAN_BILLTYPE,projectPlanMapper);
        mapperMap.put(BillTypeConst.CONSTRUCTION_DIARY_BILLTYPE,constructionDiaryMapper);
        mapperMap.put(BillTypeConst.PARALLEL_INSPECTION_BILLTYPE,siteInspectionMapper);
        mapperMap.put(BillTypeConst.SIDE_INSPECTION_BILLTYPE,siteInspectionMapper);
        mapperMap.put(BillTypeConst.PATROL_BILLTYPE,siteInspectionMapper);
        mapperMap.put(BillTypeConst.WORKSTART_BILLTYPE,workStartMapper);
        mapperMap.put(BillTypeConst.PROCESS_WRITE_BILLTYPE,planWriteMapper);
        mapperMap.put(BillTypeConst.SAFETY_RECTIFICATION_BILLTYPE, safetyRectificationMapper);
        mapperMap.put(BillTypeConst.WORKSTOP_BILLTYPE,workStopMapper);
        mapperMap.put(BillTypeConst.STAGECHECK_BILLTYPE,stageCheckMapper);
        mapperMap.put(BillTypeConst.REPEATWORK_BILLTYPE,repeatWorkMapper);
    }

    /**
     * 根据单据类型获取待办描述信息
     *
     * @param billType
     * @param pks
     * @throws BusinessException
     */
    private  Map<String, String> getTaskDescribeMap(String billType,  String[] pks) throws BusinessException {

        Map<String, String> recordInfo = new HashMap<>();

        String ids = SqlUtil.getSqlIn(pks);

        Entity[] vos = getBuziMapper(billType).getByBillIds(ids);

        switch (billType){
            case BillTypeConst.WORKCONNECT_BILLTYPE : //工作联系，标题
                if (ArrayUtils.isNotEmpty(vos)) {
                    for (WorkConnectVO vo : (WorkConnectVO[])vos) if (vo != null) recordInfo.put(vo.getPk_workconnect(), vo.getTitle());
                }
                break;
            case BillTypeConst.PROBLEMLOG_BILLTYPE : //问题记录，问题原因 + 问题描述
                if (ArrayUtils.isNotEmpty(vos)) {
                    Set<String> pkReasons = new HashSet<>();
                    for (ProblemLogVO vo : (ProblemLogVO[])vos) {
                        if (vo != null && vo.getPk_problemreason() != null)
                            pkReasons.add(vo.getPk_problemreason());
                    }
                    Map<String, ProblemReasonRefVO> reasonMap = problemReasonQuery.queryRefs(pkReasons.toArray(new String[0]));
                    for (ProblemLogVO vo : (ProblemLogVO[])vos) {
                        if (vo == null) continue;
                        if (vo.getPk_problemreason() == null || reasonMap.get(vo.getPk_problemreason()) == null) {
                            recordInfo.put(vo.getPk_problem(), "问题原因：" + "\n" + (vo.getContent() == null ? "" : vo.getContent()));
                        } else {
                            recordInfo.put(vo.getPk_problem(), "问题原因：" + reasonMap.get(vo.getPk_problemreason()).getSname() + "\n" + (vo.getContent() == null ? "" : vo.getContent()));
                        }
                    }
                }
                break;
            case BillTypeConst.SAFETY_RECTIFICATION_BILLTYPE: // 安全整改，问题原因
                addBillDescriptionForSafetyRectify(vos, recordInfo);
                break;
            case BillTypeConst.PROCEDUREINSPECT_BILLTYPE : //工序报验，工序名称
                if (ArrayUtils.isNotEmpty(vos)) {
                    Set<String> pkProcedures = new HashSet<>();
                    for (ProcedureInspectVO vo : (ProcedureInspectVO[])vos)
                        if (vo != null && vo.getPk_procedure() != null)
                            pkProcedures.add(vo.getPk_procedure());
                    if (!pkProcedures.isEmpty()) {
                        Map<String, ProcedureRefVO> recordProcedure = procedureQuery.queryRefs(pkProcedures.toArray(new String[0]));
                        for (ProcedureInspectVO vo : (ProcedureInspectVO[])vos) {
                            if (vo == null || recordProcedure.get(vo.getPk_procedure()) == null)
                                continue;
                            recordInfo.put(vo.getPk_process_inspect(), recordProcedure.get(vo.getPk_procedure()).getSname());
                        }
                    }
                }
                break;
            case BillTypeConst.ALTER_AND_VISA_BILLTYPE :   //签证申请，签证类型名称、金额
                if (ArrayUtils.isNotEmpty(vos)) {
                    Set<String> pkCategorys = new HashSet<>();
                    for (AlterAndVisaVO vo : (AlterAndVisaVO[])vos)
                        if (vo != null && vo.getPkAltervisacategory() != null)
                            pkCategorys.add(vo.getPkAltervisacategory());
                    if (!pkCategorys.isEmpty()) {
                        Map<String, String> categoryName = alterAndVisaCategoryQuery.queryNameByIds(pkCategorys.toArray(new String[0]));
                        for (AlterAndVisaVO vo : (AlterAndVisaVO[])vos) {
                            if (vo != null) {
                                recordInfo.put(vo.getPkAlterandvisa(), categoryName.get(vo.getPkAltervisacategory()) + (vo.getEstimateMny() == null ? "，未预估金额" : ", 金额：" + vo.getEstimateMny()));
                            }
                        }
                    }
                }
                break;
            case BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE : //综合验收，施工单位名称(先保存主键，因为后台没法获取名字)
                if (ArrayUtils.isNotEmpty(vos)) {
                    for (ComprehensiveAcceptanceVO vo : (ComprehensiveAcceptanceVO[])vos)
                        recordInfo.put(vo.getPkComprehensiveAcceptance(), vo.getPkConstructionunit());
                }
                break;
            case BillTypeConst.CONSTRUCTIONLOG_BILLTYPE : //施工记录，检查标准名称
                if (ArrayUtils.isNotEmpty(vos)) {
                    Set<String> inspectStandards = new HashSet<>();
                    for (ConstructionLogVO vo : (ConstructionLogVO[])vos)
                        if (vo != null && vo.getPk_inspectstandard() != null)
                            inspectStandards.add(vo.getPk_inspectstandard());
                    if (!inspectStandards.isEmpty()) {
                        Map<String, WorkqualityVO> recordWorkquality = qualityQuery.queryByIDs(inspectStandards.toArray(new String[0]));
                        for (ConstructionLogVO vo : (ConstructionLogVO[])vos) {
                            if (vo == null || recordWorkquality.get(vo.getPk_inspectstandard()) == null) continue;
                            recordInfo.put(vo.getPk_constructionlog(), recordWorkquality.get(vo.getPk_inspectstandard()).getCheckname());
                        }
                    }
                }
                break;
            case BillTypeConst.PROCESSPHOTO_BILLTYPE : //工序拍照，工序名称
                if (ArrayUtils.isNotEmpty(vos)) {
                    Set<String> pkProcedures = new HashSet<>();
                    for (ProcessPhotoVO vo : (ProcessPhotoVO[])vos)
                        if (vo != null && vo.getPk_process() != null) pkProcedures.add(vo.getPk_process());
                    if (!pkProcedures.isEmpty()) {
                        Map<String, ProcedureRefVO> recordProcedure = procedureQuery.queryRefs(pkProcedures.toArray(new String[0]));
                        for (ProcessPhotoVO vo : (ProcessPhotoVO[])vos) {
                            if (vo == null || recordProcedure.get(vo.getPk_process()) == null) continue;
                            recordInfo.put(vo.getPkProcessphoto(), recordProcedure.get(vo.getPk_process()).getSname());
                        }
                    }
                }
                break;
            case BillTypeConst.ALTER_BILLTYPE : //变更申请，变更类别名称
                if (ArrayUtils.isNotEmpty(vos)) {
                    Set<String> pkCategorys = new HashSet<>();
                    for (AlterVO vo : (AlterVO[])vos)
                        if (vo != null && vo.getPkAltercategory() != null) pkCategorys.add(vo.getPkAltercategory());
                    if (!pkCategorys.isEmpty()) {
                        Map<String, String> categoryName = alterCategoryQuery.queryNameByIds(pkCategorys.toArray(new String[0]));
                        for (AlterVO vo : (AlterVO[])vos)
                            if (vo != null) recordInfo.put(vo.getPkAlter(), categoryName.get(vo.getPkAltercategory()));
                    }
                }
                break;
            case BillTypeConst.PROCESS_PLAN_BILLTYPE : //进度计划(项目计划)，计划名称
                if (ArrayUtils.isNotEmpty(vos)) {
                    for (ProjectPlanVO vo : (ProjectPlanVO[])vos) if (vo != null) recordInfo.put(vo.getPkPlan(), vo.getSname());
                }
                break;
            case BillTypeConst.CONSTRUCTION_DIARY_BILLTYPE: //施工日志，制单日期
                if (ArrayUtils.isNotEmpty(vos)) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    for (ConstructionDiaryVO vo : (ConstructionDiaryVO[])vos)
                        if (vo != null)
                            recordInfo.put(vo.getPkConstructiondiary(), simpleDateFormat.format(vo.getCreationtime()));
                }
                break;
            case BillTypeConst.WORKSTART_BILLTYPE: //开工报告，施工单位主键
                if (ArrayUtils.isNotEmpty(vos)) {
                    for (WorkStartVO vo : (WorkStartVO[])vos){
                        if (vo != null){
                            String pkEnterprise = vo.getPkEnterprise();//施工单位主键
                            recordInfo.put(vo.getPkWorkstartreport(),pkEnterprise);
                        }
                    }

                }
                break;
            case BillTypeConst.PROCESS_WRITE_BILLTYPE: //计划填报，计划名称
                if (ArrayUtils.isNotEmpty(vos)) {
                    for (PlanWriteVO vo : (PlanWriteVO[])vos){
                        if (vo != null){
                            recordInfo.put(vo.getPkPlanwrite(),getPlanName(vo.getPkPlan()));
                        }
                    }

                }
                break;
            case BillTypeConst.WORKSTOP_BILLTYPE: //停工单  停工单名称
                if (ArrayUtils.isNotEmpty(vos)) {
                    Set<String> pkWorkstopreport = new HashSet<>();
                    for (WorkStopVO vo : (WorkStopVO[])vos){
                        if (vo != null && vo.getPkWorkstopreport() != null) pkWorkstopreport.add(vo.getPkWorkstopreport());
                    }
                    if (!pkWorkstopreport.isEmpty()) {
                        //key 项目id value 项目名称
                        Map<String, String> maps = projectSimpleQuery.queryProjectNameByIds(pkWorkstopreport.toArray(new String[0]));
                        //通过主键把所有的vo查询出来
                        Map<String, WorkStopVO> recordWorkStop = workStopQuery.queryByIds(pkWorkstopreport.toArray(new String[0]));
                        for (WorkStopVO vo : (WorkStopVO[])vos) {
                            if (vo == null || recordWorkStop.get(vo.getPkWorkstopreport()) == null) continue;
                            recordInfo.put(vo.getPkWorkstopreport(), maps.get(vo.getPkProject()));
                        }
                    }
                }
                break;
            case BillTypeConst.REPEATWORK_BILLTYPE: //复工单
                if (ArrayUtils.isNotEmpty(vos)) {
                    Set<String> pkRepeatWorkVo = new HashSet<>();
                    for(RepeatWorkVO vo: (RepeatWorkVO[]) vos){
                        if(vo!=null && vo.getPkRepeatwork() !=null){
                            pkRepeatWorkVo.add(vo.getPkRepeatwork());
                        }
                    }
                    if(!pkRepeatWorkVo.isEmpty()){
                        //key 项目主键 value 项目名称
                        Map<String,String> maps = projectSimpleQuery.queryProjectNameByIds(pkRepeatWorkVo.toArray(new String[0]));
                        //通过主键把所有的vo查询出来
                        Map<String,RepeatWorkVO> repeatWorkVOMap = repeatWorkQuery.queryByIDs(pkRepeatWorkVo.toArray(new String[0]));

                        for(RepeatWorkVO vo: (RepeatWorkVO[]) vos){
                            if (vo == null || repeatWorkVOMap.get(vo.getPkRepeatwork()) == null){
                                continue;
                            }
                            recordInfo.put(vo.getPkRepeatwork(),maps.get(vo.getPkProject()));
                        }
                    }
                }
                break;

        }
        return recordInfo;
    }

    /**
     * 添加安全整改的单据描述信息
     *
     * @param vos
     * @param recordInfo
     */
    private void addBillDescriptionForSafetyRectify(Entity[] vos, Map<String, String> recordInfo) throws BusinessException {
        if (ArrayUtils.isEmpty(vos))
            return;

        Set<String> pkReasonSet = new HashSet<>();
        for (SafetyRectificationVO vo : (SafetyRectificationVO[]) vos) {
            pkReasonSet.add(vo.getPkProblemReason());
        }

        Map<String, ProblemReasonRefVO> reasonMap = problemReasonQuery.queryRefs(pkReasonSet.toArray(new String[0]));
        if (MapUtils.isEmpty(reasonMap))
            return;

        ProblemReasonRefVO reasonRefVO;
        for (SafetyRectificationVO vo : (SafetyRectificationVO[]) vos) {
            reasonRefVO = reasonMap.get(vo.getPkProblemReason());
            if (reasonRefVO != null)
                recordInfo.put(vo.getPkSafetyRectification(), "问题原因：" + reasonRefVO.getSname());
        }
    }

    /**
     * 计划填报跟计划名称
     */
    private String getPlanName(String pkPlan){
        ProjectPlanVO projectPlanVO = projectPlanMapper.queryByPkPlan(pkPlan);
        if (projectPlanVO!=null){
            return projectPlanVO.getSname();
        }
        return null;
    }
    /**
     * 获得各业务单据的Mapper对象
     * @param billType
     * @return
     */
    private BaseMapper getBuziMapper(String billType){
        return mapperMap.get(billType);
    }


}
